<?php
/**
 * TinyMVC - TinyMVCSimpleContainer.class.php file
 *
 * @author Adrian Wieczorek <adi(at)tinymvc(dot)org>
 * @package TinyMVC
 * @version $Id: TinyMVCSimpleContainer.class.php 118 2011-07-19 13:29:42Z adi3ek $
 *
 */

/**
 * simple container implementation
 * @package TinyMVC
 */
class TinyMVCSimpleContainer implements Iterator {
	private $elements = array();
	private $keys = array();

	/**
	 * add element to container
	 * @param string $key element key
	 * @param mixed $value element value
	 */
	public function addElement($key, $value) {
		if(!empty($key)) {
			$this->elements[$key] = $value;
		}
		else {
			$this->elements[] = $value;
		}
	}

	/**
	 * Alias: {@link addElement()}
	 */
	public function add($key, $value) {
		$this->addElement($key, $value);
	}

	/**
	 * Alias: {@link addElement()}
	 */
	public function set($key, $value) {
		$this->addElement($key, $value);
	}

	/**
	 * overloaded magic method ({@link addElement()})
	 */
	public function __set($key, $value) {
		$this->addElement($key, $value);
	}

	/**
	 * get element from container
	 * @param string $key element key
	 * @param mixed $nullValue return value for non-existent key
	 * @return mixed element
	 */
	public function getElement($key, $nullValue = null) {
		return $this->isKeyExists($key) ? $this->elements[$key] : $nullValue;
	}

	/**
	 * Alias: {@link getElement()}
	 */
	public function get($key, $nullValue = null) {
		return $this->getElement($key, $nullValue = null);
	}

	/**
	 * overloaded magic method ({@link getElement()})
	 */
	public function __get($key) {
		return $this->get($key);
	}

	/**
	 * remove element from container
	 * @param string $key element key
	 */
	public function remove($key) {
		unset($this->elements[$key]);
	}

	/**
	 * get all elements from container
	 * @return array list of elements
	 */
	public function getElements() {
		return $this->elements;
	}

	/**
	 * get number of elements in container
	 * @return int number of elements
	 */
	public function getElementsNum() {
		return count($this->elements);
	}

	/**
	 * check if container is empty
	 * @return bool
	 */
	public function isEmpty() {
		return ( $this->getElementsNum() == 0 ) ? true : false;
	}

	/**
	 * check, whether or not element with given key exists
	 * @param string $key element key
	 * @return bool
	 */
	public function isKeyExists($key) {
		return array_key_exists($key, $this->elements);
	}

	/**
	 * overloaded magic method ({@link TinyMVCSimleContainer::isKeyExists})
	 */
	public function __isset($key) {
		return $this->isKeyExists($key);
	}

	/**
	 * merge container with existing one
	 * @param TinyMVCSimpleContainer $container container to be merged
	 * @param bool $skipDupes don't overwrite same key elements (default: false)
	 */
	public function merge(TinyMVCSimpleContainer $container, $skipDupes = false) {
		foreach($container as $key => $value) {
			if(!$skipDupes || ($skipDupes && !$this->isKeyExists($key))) {
				$this->addElement($key, $value);
			}
		}
	}

	public function rewind() {
		$this->keys = array_keys($this->elements);
		return $this;
	}

	public function current() {
		return $this->elements[$this->keys[0]];
	}

	public function key() {
		return $this->keys[0];
	}

	public function next() {
		array_shift($this->keys);
	}

	public function valid() {
		return count($this->keys) ? true : false;
	}
}
